package com.express.controller;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.express.annotation.AuthorityCheck;
import com.express.annotation.LogWeb;
import com.express.annotation.PassToken;
import com.express.dto.AfterPasswordDto;
import com.express.entity.SysUserTokenEntity;
import com.express.service.SysUserTokenService;
import com.express.util.*;
import io.jsonwebtoken.impl.crypto.JwtSigner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;


/**
 * 用户token
 *
 * @author Rock.Zhou
 * @email cool_fish@aliyun.com
 * @date 2020-12-25 10:49:09
 */
@RestController
@RequestMapping("/APIServer/api")
public class TokenUsersController {


    /**
     * jwt
     */
    @Autowired
    private JWTService jwtService;
    /**
     * 用户和token
     */
    @Autowired
    private SysUserTokenService userTokenService;


    /**
     * 创建用户
     * @return
     */
    @PassToken
    @PostMapping("/createUser")
    @ResponseBody
    public R createUser(@RequestBody Map<String,String> params){

        if (null == params.get("userNo") || null == params.get("userPs") || "".equals(params.get("userNo")) || "".equals(params.get("userPs"))){
            return R.error(401,"参数不全");
        }

        // 调用 查询是否重复
        int countByUserNo = userTokenService.countByUserNo(params.get("userNo"));
        if (countByUserNo > 0){
            return R.error(501,"用户名已经存在");
        }
        // 调用insert
        String pwdMD5= Md5Util.StringInMd5(params.get("userPs"));
        params.put("userPs",pwdMD5);

        boolean flag = userTokenService.createUser(params);
        if (!flag){
            return R.error(500,"用户创建失败");
        }

        return R.ok("用户创建成功");
    }


    /**
     * 登录且返回token
     * @param params
     * @return
     */
    @PassToken
    @PostMapping("/login")
    @AuthorityCheck("/login")
    public R login(@RequestBody Map<String,String> params){
        // accessToken
        String accessToken = "";
        // refreshToken
        String refreshToken = "";

        if(null == params.get("userName") || "".equals(params.get("userName"))){
            return R.error("用户名为空!,登录失败!");
        }
        if(null == params.get("password") || "".equals(params.get("password"))){
            return R.error("密码为空,登录失败!");
        }
        // 用户名
        String userName = params.get("userName");
        // 密码
        String password = params.get("password");

        // 密文密码
        String pwdMD5= Md5Util.StringInMd5(password);

        // 查询用户密码是否正确
        int count = userTokenService.countByParams(userName,pwdMD5);
        if (count <= 0){
            return R.error("用户名或密码错误!");
        }

        // 生成token
        Map<String,String> tokenMap = userTokenService.getToken(
                userName.trim()
                ,password.trim());

        // 判断token是否有值
        if (null != tokenMap.get("access_token") || !"".equals(tokenMap.get("access_token"))){
            accessToken = tokenMap.get("access_token");
        }
        if (null != tokenMap.get("refresh_token") || !"".equals(tokenMap.get("refresh_token"))){
            refreshToken = tokenMap.get("refresh_token");
        }

        if ("".equals(accessToken) || "".equals(refreshToken)){
            return R.error("申请token出错,请联系管理员!");
        }


        return R.ok().put("accessToken",accessToken);
    }

    /**
     * 申请token
     *
     * @param request
     * @param userNo
     * @param userPs
     * @return
     */
    @PassToken
    @LogWeb("申请token")
    @PostMapping("/NewToken")
    @ResponseBody
    public Response newToken(HttpServletRequest request, @RequestParam("UID") String userNo, @RequestParam("PWD") String userPs) {

        //token
        String accessToken = "";
        String refreshToken = "";

        // 如果用户名错误返回401
        if (null == userNo || userNo.equals("")) {
            return Response.error().put("401", "账号或密码错误!");
        }

        // 密文密码
        String userPsMD5= Md5Util.StringInMd5(userPs);
        // 查询创建时间为三天前的账号
        List<Map<String,Object>> resultList = userTokenService.findIsExpired(userNo, userPsMD5);

        // 如果未查到
        if (null == resultList || resultList.size() < 1) {
            return Response.error("401", userNo+"账号或者密码错误");
        }


        // 生成token
        Map<String,String> tokenMap = userTokenService.getToken(
                userNo.trim()
                ,userPsMD5.trim());
        // 判断token是否有值
        if (null != tokenMap.get("access_token") || !"".equals(tokenMap.get("access_token"))){
            accessToken = tokenMap.get("access_token");
        }else {
            return Response.error("500","申请token出错,请联系管理员!");
        }
        if (null != tokenMap.get("refresh_token") || !"".equals(tokenMap.get("refresh_token"))){
            refreshToken = tokenMap.get("refresh_token");
        }else {
            return Response.error("500","申请token出错,请联系管理员!");
        }
        return new Response().put("access_token",accessToken).put("refresh_token",refreshToken);
    }

    /**
     * 更新token
     * @param userNo
     * @param refreshToken
     * @return
     */
    @PostMapping("/RefreshToken")
    @AuthorityCheck("/APIServer/api/RefreshToken")
    @ResponseBody
    public Response refreshToken(@RequestHeader("Authentication")String token,@RequestParam("UID")String  userNo,@RequestParam("RefreshToken")String refreshToken){

        // accessToken 返回值
        String accessToken = "";
        // refreshToken 返回值
        String reRefreshToken = "";

        // 获取用户
        SysUserTokenEntity user = jwtService.getUser(token);
        if (null ==user || null == user.getUserNo()){
            return Response.error("401","未找到该用户");
        }
        if (null != user.getUserNo()){
            if (!user.getUserNo().equals(userNo)){
                return Response.error("401","未找到该用户");
            }
        }
        // 校验RefreshToken
        if (null != user.getRefreshToken() && !"".equals(user.getRefreshToken())){
            String userRefreshToken = user.getRefreshToken();
            if (!userRefreshToken.equals(refreshToken)){
                return new Response().put("401","无效refreshToken");
            }
        }else {
            return new Response().put("401","无效refreshToken");
        }

        // 生成token
        Map<String,String> tokenMap = userTokenService.getDoubleToken(user);

        // 判断token是否有值
        if (null != tokenMap.get("access_token") || !"".equals(tokenMap.get("access_token"))){
            accessToken = tokenMap.get("access_token");
        }
        if (null != tokenMap.get("refresh_token") || !"".equals(tokenMap.get("refresh_token"))){
            reRefreshToken = tokenMap.get("refresh_token");
        }

        if ("".equals(accessToken) || "".equals(reRefreshToken)){
            return Response.error("500","申请token出错,请联系管理员!");
        }

        return new Response().put("access_token",accessToken).put("refresh_token",reRefreshToken);
    }

    /**
     * 检查token
     * @param token
     * @return
     */
    @PostMapping("/VerifyToken")
    @AuthorityCheck("/APIServer/api/VerifyToken")
    @ResponseBody
    public Response verifyToken(@RequestHeader("Authentication")String token){
        if (null == token || token.trim().equals("")){
            return Response.error("401","无效token");
        }
        Boolean flag = jwtService.decryptToken(token);
        if (!flag){
            return new Response("401","无效token");
        }
        return Response.ok("token认证成功");
    }

    /**
     * 修改密码
     * @param token
     * @param params
     * @return
     */
    @PostMapping("/afterPassword")
    @ResponseBody
    public R afterPassword (@RequestHeader("Authentication")String token, @RequestBody AfterPasswordDto params){
        SysUserTokenEntity user = jwtService.getUser(token);
        String userPs = user.getUserPs();
        String md5pwd = "";
        String md5afterPwd = "";
        if (null == params.getMd5pwd() || "".equals(params.getMd5pwd())){
            return R.error("错误，原密码为空！");
        }else {
            md5pwd = params.getMd5pwd();
        }
        if (null == params.getMd5afterPwd() || "".equals(params.getMd5afterPwd())){
            return R.error("错误，修改密码为空！");
        }else {
            md5afterPwd = params.getMd5afterPwd();
        }
        if (!userPs.equals(md5pwd)){
            return R.error("原密码错误，修改密码失败！");
        }else {
            int update = userTokenService.afterPassword(user,md5afterPwd);
            if (1 == update){
                return R.ok("密码已修改成功!");
            }
        }
        return R.error();
    }
}
